<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Amazon Lambda</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/amazon-lambda" />
  <meta property="og:title" content="Quarkus - Amazon Lambda" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/amazon-lambda">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Amazon Lambda</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#getting-started">Getting Started</a></li>
<li><a href="#installing-aws-bits">Installing AWS bits</a></li>
<li><a href="#creating-the-maven-deployment-project">Creating the Maven Deployment Project</a></li>
<li><a href="#choose">Choose Your Lambda</a></li>
<li><a href="#deploy-to-aws-lambda-java-runtime">Deploy to AWS Lambda Java Runtime</a></li>
<li><a href="#build-and-deploy">Build and Deploy</a></li>
<li><a href="#create-an-execution-role">Create an Execution Role</a></li>
<li><a href="#extra-build-generated-files">Extra Build Generated Files</a></li>
<li><a href="#create-the-function">Create the function</a></li>
<li><a href="#invoke-the-lambda">Invoke the Lambda</a></li>
<li><a href="#update-the-lambda">Update the Lambda</a></li>
<li><a href="#deploy-to-aws-lambda-custom-native-runtime">Deploy to AWS Lambda Custom (native) Runtime</a></li>
<li><a href="#examine-the-pom-and-gradle-build">Examine the POM and Gradle build</a></li>
<li><a href="#gradle">Gradle build</a></li>
<li><a href="#integration-testing">Integration Testing</a></li>
<li><a href="#testing-with-the-sam-cli">Testing with the SAM CLI</a></li>
<li><a href="#modifying-function-zip">Modifying <code>function.zip</code></a></li>
<li><a href="#custom-bootstrap-script">Custom <code>bootstrap</code> script</a></li>
<li><a href="#tracing-with-aws-xray-and-graalvm">Tracing with AWS XRay and GraalVM</a></li>
<li><a href="#https">Using HTTPS or SSL/TLS</a></li>
<li><a href="#aws-sdk-v2">Using the AWS Java SDK v2</a></li>
<li><a href="#additional-requirements-for-client-ssl">Additional requirements for client SSL</a></li>
<li><a href="#amazon-alexa-integration">Amazon Alexa Integration</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>The <code>quarkus-amazon-lambda</code> extension allows you to use Quarkus to build your AWS Lambdas.
Your lambdas can use injection annotations from CDI or Spring and other Quarkus facilities as you need them.</p>
</div>
<div class="paragraph">
<p>Quarkus lambdas can be deployed using the Amazon Java Runtime, or you can build a native executable and use
Amazon&#8217;s Custom Runtime if you want a smaller memory footprint and faster cold boot startup time.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This technology is considered preview.</p>
</div>
<div class="paragraph">
<p>In <em>preview</em>, backward compatibility and presence in the ecosystem is not guaranteed.
Specific improvements might require to change configuration or APIs and plans to become <em>stable</em> are under way.
Feedback is welcome on our <a href="https://groups.google.com/d/forum/quarkus-dev">mailing list</a> or as issues in our <a href="https://github.com/quarkusio/quarkus/issues">GitHub issue tracker</a>.</p>
</div>
<div class="paragraph">
<p>For a full list of possible extension statuses, check our <a href="https://quarkus.io/faq/#extension-status">FAQ entry</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 30 minutes</p>
</li>
<li>
<p>JDK 11 (AWS requires JDK 1.8 or 11)</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
<li>
<p><a href="https://aws.amazon.com">An Amazon AWS account</a></p>
</li>
<li>
<p><a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html">AWS CLI</a></p>
</li>
<li>
<p><a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html">AWS SAM CLI</a>, for local testing</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
For Gradle projects please <a href="#gradle">see below</a>, or for further reference consult the guide in the <a href="gradle-tooling">Gradle setup page</a>.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="getting-started"><a class="anchor" href="#getting-started"></a>Getting Started</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This guide walks you through generating an example Java project via a maven archetype and deploying it to AWS.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="installing-aws-bits"><a class="anchor" href="#installing-aws-bits"></a>Installing AWS bits</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Installing all the AWS bits is probably the most difficult thing about this guide.  Make sure that you follow all the steps
for installing AWS CLI.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-maven-deployment-project"><a class="anchor" href="#creating-the-maven-deployment-project"></a>Creating the Maven Deployment Project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Create the Quarkus AWS Lambda maven project using our Maven Archetype.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn archetype:generate \
       -DarchetypeGroupId=io.quarkus \
       -DarchetypeArtifactId=quarkus-amazon-lambda-archetype \
       -DarchetypeVersion=1.7.0.Final</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If you prefer to use Gradle, you can quickly and easily generate a Gradle project via <a href="https://code.quarkus.io/">code.quarkus.io</a>
adding the <code>quarkus-amazon-lambda</code> extension as a dependency.</p>
</div>
<div class="paragraph">
<p>Copy the build.gradle, gradle.properties and settings.gradle into the above generated Maven archetype project, to follow along with this guide.</p>
</div>
<div class="paragraph">
<p>Execute: gradle wrapper to setup the gradle wrapper (recommended).</p>
</div>
<div class="paragraph">
<p>The dependency for <code>quarkus-test-amazon-lambda</code> will also need to be added to your build.gradle.</p>
</div>
<div class="paragraph">
<p>For full Gradle details <a href="#gradle">see below</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="choose"><a class="anchor" href="#choose"></a>Choose Your Lambda</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>quarkus-amazon-lambda</code> extension scans your project for a class that directly implements the Amazon <code>RequestHandler&lt;?, ?&gt;</code> or <code>RequestStreamHandler</code> interface.
It must find a class in your project that implements this interface or it will throw a build time failure.
If it finds more than one handler class, a build time exception will also be thrown.</p>
</div>
<div class="paragraph">
<p>Sometimes, though, you might have a few related lambdas that share code and creating multiple maven modules is just
an overhead you don&#8217;t want to do.  The <code>quarkus-amazon-lambda</code> extension allows you to bundle multiple lambdas in one
project and use configuration or an environment variable to pick the handler you want to deploy.</p>
</div>
<div class="paragraph">
<p>The generated project has three lambdas within it.  Two that implement the <code>RequestHandler&lt;?, ?&gt;</code> interface, and one that implements the <code>RequestStreamHandler</code> interface. One that is used and two that are unused.  If you open up
<code>src/main/resources/application.properties</code> you&#8217;ll see this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.lambda.handler=test</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>quarkus.lambda.handler</code> property tells Quarkus which lambda handler to deploy. This can be overridden
with an environment variable too.</p>
</div>
<div class="paragraph">
<p>If you look at the three generated handler classes in the project, you&#8217;ll see that they are <code>@Named</code> differently.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">@Named("test")
public class TestLambda implements RequestHandler&lt;InputObject, OutputObject&gt; {
}

@Named("unused")
public class UnusedLambda implements RequestHandler&lt;InputObject, OutputObject&gt; {
}

@Named("stream")
public class StreamLambda implements RequestStreamHandler {
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The CDI name of the handler class must match the value specified within the <code>quarkus.lambda.handler</code> property.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="deploy-to-aws-lambda-java-runtime"><a class="anchor" href="#deploy-to-aws-lambda-java-runtime"></a>Deploy to AWS Lambda Java Runtime</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are a few steps to get your lambda running on AWS.  The generated maven project contains a helpful script to
create, update, delete, and invoke your lambdas for pure Java and native deployments.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="build-and-deploy"><a class="anchor" href="#build-and-deploy"></a>Build and Deploy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Build the project using maven.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">./mvnw clean package</code></pre>
</div>
</div>
<div class="paragraph">
<p>or, if using Gradle:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>./gradlew clean assemble</pre>
</div>
</div>
<div class="paragraph">
<p>This will compile and package your code.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="create-an-execution-role"><a class="anchor" href="#create-an-execution-role"></a>Create an Execution Role</h2>
<div class="sectionbody">
<div class="paragraph">
<p>View the <a href="https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html">Getting Started Guide</a> for deploying
a lambda with AWS CLI.  Specifically, make sure you have created an <code>Execution Role</code>.  You will need to define
a <code>LAMBDA_ROLE_ARN</code> environment variable in your profile or console window,  Alternatively, you can edit
the <code>manage.sh</code> script that is generated by the build and put the role value directly there:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">LAMBDA_ROLE_ARN="arn:aws:iam::1234567890:role/lambda-role"</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="extra-build-generated-files"><a class="anchor" href="#extra-build-generated-files"></a>Extra Build Generated Files</h2>
<div class="sectionbody">
<div class="paragraph">
<p>After you run the build, there are a few extra files generated by the <code>quarkus-amazon-lambda</code> extension.  These files
are in the the build directory:  <code>target/</code> for maven, <code>build/</code> for gradle.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>function.zip</code> - lambda deployment file</p>
</li>
<li>
<p><code>manage.sh</code> - wrapper around aws lamba cli calls</p>
</li>
<li>
<p><code>bootstrap-example.sh</code> - example bootstrap script for native deployments</p>
</li>
<li>
<p><code>sam.jvm.yaml</code> - (optional) for use with sam cli and local testing</p>
</li>
<li>
<p><code>sam.native.yaml</code> - (optional) for use with sam cli and native local testing</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="create-the-function"><a class="anchor" href="#create-the-function"></a>Create the function</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>target/manage.sh</code> script is for managing your lambda using the AWS Lambda Java runtime.  This script is provided only for
your convenience. Examine the output of the <code>manage.sh</code> script if you want to learn what aws commands are executed
to create, delete, and update your lambdas.</p>
</div>
<div class="paragraph">
<p><code>manage.sh</code> supports four operation:  <code>create</code>, <code>delete</code>, <code>update</code>, and <code>invoke</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
To verify your setup, that you have the AWS CLI installed, executed aws configure for the AWS access keys,
and setup the <code>LAMBDA_ROLE_ARN</code> environment variable (as described above), please execute <code>manage.sh</code> without any parameters.
A usage statement will be printed to guide you accordingly.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If using Gradle, the path to the binaries in the <code>manage.sh</code> must be changed from <code>target</code> to <code>build</code>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To see the <code>usage</code> statement, and validate AWS configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sh target/manage.sh</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can <code>create</code> your function using the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sh target/manage.sh create</code></pre>
</div>
</div>
<div class="paragraph">
<p>or if you do not have <code>LAMBDA_ROLE_ARN</code> already defined in this shell:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">LAMBDA_ROLE_ARN="arn:aws:iam::1234567890:role/lambda-role" sh target/manage.sh create</code></pre>
</div>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
Do not change the handler switch.  This must be hardcoded to <code>io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest</code>.  This
handler bootstraps Quarkus and wraps your actual handler so that injection can be performed.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If there are any problems creating the function, you must delete it with the <code>delete</code> function before re-running
the <code>create</code> command.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sh target/manage.sh delete</code></pre>
</div>
</div>
<div class="paragraph">
<p>Commands may also be stacked:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sh target/manage.sh delete create</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="invoke-the-lambda"><a class="anchor" href="#invoke-the-lambda"></a>Invoke the Lambda</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Use the <code>invoke</code> command to invoke your function.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sh target/manage.sh invoke</code></pre>
</div>
</div>
<div class="paragraph">
<p>The example lambda takes input passed in via the <code>--payload</code> switch which points to a json file
in the root directory of the project.</p>
</div>
<div class="paragraph">
<p>The lambda can also be invoked locally with the SAM CLI like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sam local invoke --template target/sam.jvm.yaml --event payload.json</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you are working with your native image build, simply replace the template name with the native version:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sam local invoke --template target/sam.native.yaml --event payload.json</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="update-the-lambda"><a class="anchor" href="#update-the-lambda"></a>Update the Lambda</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can update the Java code as you see fit.  Once you&#8217;ve rebuilt, you can redeploy your lambda by executing the
<code>update</code> command.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sh target/manage.sh update</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="deploy-to-aws-lambda-custom-native-runtime"><a class="anchor" href="#deploy-to-aws-lambda-custom-native-runtime"></a>Deploy to AWS Lambda Custom (native) Runtime</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you want a lower memory footprint and faster initialization times for your lambda, you can compile your Java
code to a native executable.  Just make sure to rebuild your project with the <code>-Pnative</code> switch.</p>
</div>
<div class="paragraph">
<p>For Linux hosts execute:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn package -Pnative</code></pre>
</div>
</div>
<div class="paragraph">
<p>or, if using Gradle:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">./gradlew build -Dquarkus.package.type=native</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If you are building on a non-Linux system, you will need to also pass in a property instructing quarkus to use a docker build as Amazon
Lambda requires linux binaries.  You can do this by passing this property to your Maven build:
<code>-Dnative-image.docker-build=true</code>, or for Gradle: <code>--docker-build=true</code>.  This requires you to have docker installed locally, however.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">./mvnw clean install -Pnative -Dnative-image.docker-build=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>or, if using Gradle:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>Either of these commands will compile and create a native executable image.  It also generates a zip file <code>target/function.zip</code>.
This zip file contains your native executable image renamed to <code>bootstrap</code>.  This is a requirement of the AWS Lambda
Custom (Provided) Runtime.</p>
</div>
<div class="paragraph">
<p>The instructions here are exactly as above with one change:  you&#8217;ll need to add <code>native</code> as the first parameter to the
<code>manage.sh</code> script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sh target/manage.sh native create</code></pre>
</div>
</div>
<div class="paragraph">
<p>As above, commands can be stacked.  The only requirement is that <code>native</code> be the first parameter should you wish
to work with native image builds.  The script will take care of the rest of the details necessary to manage your native
image function deployments.</p>
</div>
<div class="paragraph">
<p>Examine the output of the <code>manage.sh</code> script if you want to learn what aws commands are executed
to create, delete, and update your lambdas.</p>
</div>
<div class="paragraph">
<p>One thing to note about the create command for native is that the <code>aws lambda create-function</code>
call must set a specific environment variable:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">--environment 'Variables={DISABLE_SIGNAL_HANDLERS=true}'</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="examine-the-pom-and-gradle-build"><a class="anchor" href="#examine-the-pom-and-gradle-build"></a>Examine the POM and Gradle build</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There is nothing special about the POM other than the inclusion of the <code>quarkus-amazon-lambda</code> and <code>quarkus-test-amazon-lambda</code> extensions
as a dependencies.  The extension automatically generates everything you might need for your lambda deployment.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
In previous versions of this extension you had to set up your pom or gradle
to zip up your executable for native deployments, but this is not the case anymore.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="gradle"><a class="anchor" href="#gradle"></a>Gradle build</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Similarly for Gradle projects, you also just have to add the <code>quarkus-amazon-lambda</code> and
<code>quarkus-test-amazon-lambda</code> dependencies.  The extension automatically generates everything you might need
for your lambda deployment.</p>
</div>
<div class="paragraph">
<p>Example Gradle dependencies:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="groovy" class="language-groovy hljs">dependencies {
    implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
    implementation 'io.quarkus:quarkus-resteasy'
    implementation 'io.quarkus:quarkus-amazon-lambda'

    testimplementation  "io.quarkus:quarkus-test-amazon-lambda"

    testImplementation 'io.quarkus:quarkus-junit5'
    testImplementation 'io.rest-assured:rest-assured'
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="integration-testing"><a class="anchor" href="#integration-testing"></a>Integration Testing</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Quarkus Amazon Lambda extension has a matching test framework that provides functionality to execute standard JUnit tests on your AWS Lambda function,
via the integration layer that Quarkus provides.  This is true for both JVM and native modes.
It provides similar functionality to the SAM CLI, without the overhead of Docker.</p>
</div>
<div class="paragraph">
<p>To illustrate, the project generated by the Maven archetype, generates a JUnit test for the <code>RequestHandler&lt;?, ?&gt;</code> implementation, which is shown below.
The test replicates the execution environment, for the function that is selected for invocation, as described <a href="#choose">above</a>.</p>
</div>
<div class="paragraph">
<p>To use the integration tests in your project there is a required property, in <code>src/test/resources/application.properties</code>. If not included, the integration tests will be in a constant loop.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">quarkus.lambda.enable-polling-jvm-mode=true</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If you are following along with the example Maven archetype project for AWS Lambda in this guide,
it includes the required property <code>quarkus.lambda.enable-polling-jvm-mode=true</code> in the test <code>application.properties</code>.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@QuarkusTest
public class LambdaHandlerTest {

    @Test
    public void testSimpleLambdaSuccess() throws Exception {
        InputObject in = new InputObject();
        in.setGreeting("Hello");
        in.setName("Stu");

        OutputObject out = LambdaClient.invoke(OutputObject.class, in);

        Assertions.assertEquals("Hello Stu", out.getResult());
        Assertions.assertTrue(out.getRequestId().matches("aws-request-\\d"), "Expected requestId as 'aws-request-&lt;number&gt;'");
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Similarly, if you are using a <code>RequestStreamHandler</code> implementation, you can add a matching JUnit test, like below,
which aligns to the generated <code>StreamLambda</code> class in the generated project.</p>
</div>
<div class="paragraph">
<p>Obviously, these two types of tests are mutually exclusive.  You must have a test that corresponds to the implemented AWS Lambda interfaces,
whether <code>RequestHandler&lt;?, ?&gt;</code> or <code>RequestStreamHandler</code>.</p>
</div>
<div class="paragraph">
<p>Two versions of the Test for <code>RequestStreamHandler</code> are presented below.  You can use either, depending on
the needs of your Unit test.  The first is obviously simpler and quicker.  Using Java streams can require more coding.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@QuarkusTest
public class LambdaStreamHandlerTest {

    private static Logger LOG = Logger.getLogger(LambdaStreamHandlerTest.class);

    @Test
    public void testSimpleLambdaSuccess() throws Exception {
        String out = LambdaClient.invoke(String.class, "lowercase");
        Assertions.assertEquals("LOWERCASE", out);
    }

    @Test
    public void testInputStreamSuccess() {
        try {
            String input = "{ \"name\": \"Bill\", \"greeting\": \"hello\"}";
            InputStream inputStream = new ByteArrayInputStream(input.getBytes());
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

            LambdaClient.invoke(inputStream, outputStream);

            ByteArrayInputStream out = new ByteArrayInputStream(outputStream.toByteArray());
            StringBuilder response = new StringBuilder();
            int i = 0;
            while ((i = out.read()) != -1) {
                response.append((char)i);
            }

            Assertions.assertTrue(response.toString().contains("BILL"));
        } catch (Exception e) {
            Assertions.fail(e.getMessage());
        }
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If your code uses CDI injection, this too will be executed, along with mocking functionality, see the <a href="getting-started-testing">Test Guide</a> for more details.</p>
</div>
<div class="paragraph">
<p>To add JUnit functionality for native tests, add the <code>@NativeImageTest</code> annotation to a subclass of your test class, which will execute against your native image, and can be leveraged in an IDE.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="testing-with-the-sam-cli"><a class="anchor" href="#testing-with-the-sam-cli"></a>Testing with the SAM CLI</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html">AWS SAM CLI</a>
allows you to run your lambdas locally on your laptop in a simulated Lambda environment.  This requires
<a href="https://www.docker.com/products/docker-desktop">docker</a> to be installed.  This is an optional approach should you choose
to take advantage of it.  Otherwise, the Quarkus JUnit integration should be sufficient for most of your needs.</p>
</div>
<div class="paragraph">
<p>A starter template has been generated for both JVM and native execution modes.</p>
</div>
<div class="paragraph">
<p>Run the following SAM CLI command to locally test your lambda function, passing the appropriate SAM <code>template</code>.
The <code>event</code> parameter takes any JSON file, in this case the sample <code>payload.json</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If using Gradle, the path to the binaries in the YAML templates must be changed from <code>target</code> to <code>build</code>
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sam local invoke --template target/sam.jvm.yaml --event payload.json</code></pre>
</div>
</div>
<div class="paragraph">
<p>The native image can also be locally tested using the <code>sam.native.yaml</code> template:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">sam local invoke --template target/sam.native.yaml --event payload.json</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="modifying-function-zip"><a class="anchor" href="#modifying-function-zip"></a>Modifying <code>function.zip</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The are times where you may have to add some additions to the <code>function.zip</code> lambda deployment that is generated
by the build.  To do this create a <code>zip.jvm</code> or <code>zip.native</code> directory within <code>src/main</code>.
Create <code>zip.jvm/</code> if you are doing a pure Java lambda.  <code>zip.native/</code> if you are doing a native deployment.</p>
</div>
<div class="paragraph">
<p>Any you files and directories you create under your zip directory will be included within <code>function.zip</code></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="custom-bootstrap-script"><a class="anchor" href="#custom-bootstrap-script"></a>Custom <code>bootstrap</code> script</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are times you may want to set a specific system properties or other arguments when lambda invokes
your native quarkus lambda deployment.  If you include a <code>bootstrap</code> script file within
<code>zip.native</code>, the quarkus extension will automatically rename the executable to <code>runner</code> within
<code>function.zip</code> and set the unix mode of the <code>bootstrap</code> script to executable.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The native executable must be referenced as <code>runner</code> if you include a custom <code>bootstrap</code> script.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The extension generates an example script within <code>target/bootstrap-example.sh</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="tracing-with-aws-xray-and-graalvm"><a class="anchor" href="#tracing-with-aws-xray-and-graalvm"></a>Tracing with AWS XRay and GraalVM</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you are building native images, and want to use <a href="https://aws.amazon.com/xray">AWS X-Ray Tracing</a> with your lambda
you will need to include <code>quarkus-amazon-lambda-xray</code> as a dependency in your pom.  The AWS X-Ray
library is not fully compatible with GraalVM so we had to do some integration work to make this work.</p>
</div>
<div class="paragraph">
<p>In addition, remember to enable the AWS X-Ray tracing parameter in <code>manage.sh</code>, in the <code>cmd_create()</code> function.  This can also be set in the AWS Management Console.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">    --tracing-config Mode=Active</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the sam template files, add the following to the YAML function Properties.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">    Tracing: Active</code></pre>
</div>
</div>
<div class="paragraph">
<p>AWS X-Ray does add many classes to your distribution, do ensure you are using at least the 256MB AWS Lambda memory size.
This is explicitly set in <code>manage.sh</code> <code>cmd_create()</code>. Whilst the native image potentially can always use a lower memory setting, it would be recommended to keep the setting the same, especially to help compare performance.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="https"><a class="anchor" href="#https"></a>Using HTTPS or SSL/TLS</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If your code makes HTTPS calls, such as to a micro-service (or AWS service), you will need to add configuration to the native image,
as GraalVM will only include the dependencies when explicitly declared.  Quarkus, by default enables this functionality on extensions that implicitly require it.
For further information, please consult the <a href="native-and-ssl">Quarkus SSL guide</a></p>
</div>
<div class="paragraph">
<p>Open src/main/resources/application.properties and add the following line to enable SSL in your native image.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.ssl.native=true</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="aws-sdk-v2"><a class="anchor" href="#aws-sdk-v2"></a>Using the AWS Java SDK v2</h2>
<div class="sectionbody">
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Quarkus now has extensions for DynamoDB, S3, SNS and SQS (more coming). Please check those guides on how to use the various AWS Services with Quarkus, as opposed to wiring manually like below.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>With minimal integration, it is possible to leverage the AWS Java SDK v2,
which can be used to invoke services such as SQS, SNS, S3 and DynamoDB.</p>
</div>
<div class="paragraph">
<p>For native image, however the URL Connection client must be preferred over the Apache HTTP Client
when using synchronous mode, due to issues in the GraalVM compilation (at present).</p>
</div>
<div class="paragraph">
<p>Add <code>quarkus-jaxb</code> as a dependency in your Maven <code>pom.xml</code>, or Gradle <code>build.gradle</code> file.</p>
</div>
<div class="paragraph">
<p>You must also force your AWS service client for SQS, SNS, S3 et al, to use the URL Connection client,
which connects to AWS services over HTTPS, hence the inclusion of the SSL enabled property, as described in the <a href="#https">Using HTTPS or SSL/TLS</a> section above.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// select the appropriate client, in this case SQS, and
// insert your region, instead of XXXX, which also improves startup time over the default client
  client = SqsClient.builder().region(Region.XXXX).httpClient(software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient.builder().build()).build();</code></pre>
</div>
</div>
<div class="paragraph">
<p>For Maven, add the following to your <code>pom.xml</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">    &lt;properties&gt;
        &lt;aws.sdk2.version&gt;2.10.69&lt;/aws.sdk2.version&gt;
    &lt;/properties&gt;

    &lt;dependencyManagement&gt;
        &lt;dependencies&gt;

            &lt;dependency&gt;
                &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
                &lt;artifactId&gt;bom&lt;/artifactId&gt;
                &lt;version&gt;${aws.sdk2.version}&lt;/version&gt;
                &lt;type&gt;pom&lt;/type&gt;
                &lt;scope&gt;import&lt;/scope&gt;
            &lt;/dependency&gt;

        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;
    &lt;dependencies&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
            &lt;artifactId&gt;url-connection-client&lt;/artifactId&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
            &lt;artifactId&gt;apache-client&lt;/artifactId&gt;
            &lt;exclusions&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;commons-logging&lt;/groupId&gt;
                    &lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
                &lt;/exclusion&gt;
            &lt;/exclusions&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
            &lt;!-- sqs/sns/s3 etc --&gt;
            &lt;artifactId&gt;sqs&lt;/artifactId&gt;
            &lt;exclusions&gt;
                &lt;!-- exclude the apache-client and netty client --&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
                    &lt;artifactId&gt;apache-client&lt;/artifactId&gt;
                &lt;/exclusion&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
                    &lt;artifactId&gt;netty-nio-client&lt;/artifactId&gt;
                &lt;/exclusion&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;commons-logging&lt;/groupId&gt;
                    &lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
                &lt;/exclusion&gt;
            &lt;/exclusions&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.jboss.logging&lt;/groupId&gt;
            &lt;artifactId&gt;commons-logging-jboss-logging&lt;/artifactId&gt;
            &lt;version&gt;1.0.0.Final&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
if you see <code>java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty</code> or similar SSL error, due to the current status of GraalVM,
there is some additional work to bundle the <code>function.zip</code>, as below.  For more information, please see the <a href="native-and-ssl">Quarkus Native SSL Guide</a>.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="additional-requirements-for-client-ssl"><a class="anchor" href="#additional-requirements-for-client-ssl"></a>Additional requirements for client SSL</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The native executable requires some additional steps to enable client ssl that S3 and other aws libraries need.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A custom <code>bootstrap</code> script</p>
</li>
<li>
<p><code>libsunec.so</code> must be added to <code>function.zip</code></p>
</li>
<li>
<p><code>cacerts</code> must be added to <code>function.zip</code></p>
</li>
</ol>
</div>
<div class="paragraph">
<p>To do this, first create a directory <code>src/main/zip.native/</code> with your build.  Next create a shell script file called <code>bootstrap</code>
within <code>src/main/zip.native/</code>, like below. An example is create automatically in your build folder (target or build), called <code>bootstrap-example.sh</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">#!/usr/bin/env bash

./runner -Djava.library.path=./ -Djavax.net.ssl.trustStore=./cacerts</code></pre>
</div>
</div>
<div class="paragraph">
<p>Additional set <code>-Djavax.net.ssl.trustStorePassword=changeit</code> if your <code>cacerts</code> file is password protected.</p>
</div>
<div class="paragraph">
<p>Next you must copy some files from your GraalVM distribution into <code>src/main/zip.native/</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
GraalVM versions can have different paths for these files, and whether you using the Java 8 or 11 version. Adjust accordingly.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">cp $GRAALVM_HOME/lib/libsunec.so $PROJECT_DIR/src/main/zip.native/
cp $GRAALVM_HOME/lib/security/cacerts $PROJECT_DIR/src/main/zip.native/</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now when you run the native build all these files will be included within <code>function.zip</code></p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If you are using a Docker image to build, then you must extract these files from this image.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To extract the required ssl, you must start up a Docker container in the background, and attach to that container to copy the artifacts.</p>
</div>
<div class="paragraph">
<p>First, let&#8217;s start the GraalVM container, noting the container id output.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">docker run -it -d --entrypoint bash quay.io/quarkus/ubi-quarkus-native-image:20.1.0-java11

# This will output a container id, like 6304eea6179522aff69acb38eca90bedfd4b970a5475aa37ccda3585bc2abdde
# Note this value as we will need it for the commands below</code></pre>
</div>
</div>
<div class="paragraph">
<p>First, libsunec.so, the C library used for the SSL implementation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">docker cp {container-id-from-above}:/opt/graalvm/jre/lib/amd64/libsunec.so src/main/zip.native/</code></pre>
</div>
</div>
<div class="paragraph">
<p>Second, cacerts, the certificate store.  You may need to periodically obtain an updated copy, also.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">docker cp {container-id-from-above}:/opt/graalvm/jre/lib/security/cacerts src/main/zip.native/</code></pre>
</div>
</div>
<div class="paragraph">
<p>Your final archive will look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">jar tvf target/function.zip

    bootstrap
    runner
    cacerts
    libsunec.so</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="amazon-alexa-integration"><a class="anchor" href="#amazon-alexa-integration"></a>Amazon Alexa Integration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To use Alexa with Quarkus native, please add the following extension.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">        &lt;dependency&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-amazon-alexa&lt;/artifactId&gt;
        &lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Create your Alexa handler, as normal, by sub-classing the abstract <code>com.amazon.ask.SkillStreamHandler</code>, and add your request handler implementation.</p>
</div>
<div class="paragraph">
<p>That&#8217;s all there is to it!</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
